package com.goingup.domain;

import java.util.ArrayList;
import java.util.List;

import com.goingup.domain.Vector.Direction;

/**
 * A building floor.
 * @author pcresswell
 *
 */
public class Floor {

	public static final Floor NONE = null;
	private int number;
	private Floor floorAbove;
	private Floor floorBelow;
	private Building building;
	private Passengers passengers = new Passengers();
	
	public Floor(int number, Building building) {
		this.number=number;
		this.building = building;
	}
	public int getNumber(){
		return number;
	}
	/**
	 * Request elevator for a pickup heading in the direction.
	 * @param direction
	 */
	public void requestElevator(Direction direction){
		building.requestPickupOn(this,direction);
	}
	public void addPassenger(Passenger passenger){
		passengers.add(passenger);
		passenger.setFloor(this);
	}
	/**
	 * The floor above.
	 * @return
	 */
	public Floor above(){
		return floorAbove;
	}
	/**
	 * Return the next floor when headed in the given direction.
	 * @param direction
	 * @return
	 */
	public Floor next(Direction direction){
		if (Direction.DOWN.equals(direction))
			return below();
		else
			return above();
	}
	/**
	 * The floor below.
	 * @return
	 */
	public Floor below(){
		return floorBelow;
	}
	/**
	 * Set the floor above
	 * @param floor
	 */
	protected void setAbove(Floor floor) {
		floorAbove = floor;
		floor.setBelow(this);
	}
	/**
	 * Set the floor below
	 * @param floor
	 */
	protected void setBelow(Floor floor) {
		floorBelow = floor;
	}
	/**
	 * Get all passengers on this floor, regardless if they have a destination or not.
	 * @return
	 */
	private Passengers getPassengers(){
		return passengers;
	}
	/**
	 * Returns true if the floor has passengers that have a destination
	 * @return
	 */
	public boolean hasPassengers(){
		if (getPassengers().isEmpty())
			return false;
		for (Passenger passenger : passengers) {
			if (passenger.hasDestination())
				return true;
		}
		return false;
		
	}
	public boolean isBelow(Floor floor){
		return getNumber()<floor.getNumber();
	}
	public boolean isAbove(Floor floor){
		return getNumber()>floor.getNumber();
	}
	@Override
	public String toString() {
		return String.valueOf(getNumber());
	}
	public void boardPassengers(Elevator elevator) {
		List<Passenger> boardingPassengers = new ArrayList<Passenger>();
		
		for (Passenger passenger : passengers) {
			if (elevator.atCapacity())
				break;
			if (passenger.hasDestination()){
				try {
					passenger.board(elevator);
					boardingPassengers.add(passenger);
				} catch (MaximumCapacityExceededException e) {
					e.printStackTrace();
					break;
				}
			}
		}
		passengers.removeAll(boardingPassengers);
	}

}
